#include "RingQueue.hpp"
#include "Thread.hpp"
#include "Task.hpp"
#include <functional>
#include <memory>
#include <vector>
using namespace ThreadModule;

using ringqueue_t = RingQueue<task_t>;

void MasterCore(ringqueue_t& rq)
{
    sleep(3);
    while(true)
    {
        int t = rand() % 3;
        rq.EnQueue(tasks[t]);
        std::cout << "master product a task...\n";
        sleep(1);
    }
}

void SlaverCore(ringqueue_t& rq)
{
    // sleep(3);
    while(true)
    {
        task_t t;
        rq.DeQueue(t);
        std::cout << "slaver consum a task...\n";
        t();
        // sleep(1);
    }
}


void Init(std::vector<Thread<ringqueue_t>>& threads, int num, ringqueue_t& rq, const std::string& nameprefix, func_t<ringqueue_t> func)
{
    for (int i = 0; i < num; i++)
    {
        std::string name = nameprefix + std::to_string(i + 1);
        threads.emplace_back(func, rq, name);
    }
}

void InitMaster(std::vector<Thread<ringqueue_t>>& threads, int num, ringqueue_t& rq)
{
    Init(threads, num, rq, "master", MasterCore);
}

void InitSlaver(std::vector<Thread<ringqueue_t>>& threads, int num, ringqueue_t& rq)
{
    Init(threads, num, rq, "slaver", SlaverCore);
}

void StartAll(std::vector<Thread<ringqueue_t>>& threads)
{
    for (auto& thread : threads)
        thread.Start();
}

void WaitAll(std::vector<Thread<ringqueue_t>>& threads)
{
    for (auto& thread : threads)
        thread.Join();
}

int main()
{
    srand(time(nullptr));
    ringqueue_t* rq = new ringqueue_t();
    std::vector<Thread<ringqueue_t>> threads;
    InitMaster(threads, 1, *rq);
    InitSlaver(threads, 2, *rq);
    StartAll(threads);
    WaitAll(threads);
    return 0;
}


// using ringqueue_t = RingQueue<int>;

// void MasterCore(ringqueue_t& rq)
// {
//     // sleep(3);
//     while(true)
//     {
//         int t = rand() % 100000;
//         rq.EnQueue(t);
//         std::cout << "master product a num : " << t << std::endl;
//         // sleep(1);
//     }
// }

// void SlaverCore(ringqueue_t& rq)
// {
//     sleep(3);
//     while(true)
//     {
//         int r;
//         rq.DeQueue(r);
//         std::cout << "slaver consume a num : " << r << std::endl;
//         sleep(1);
//     }
// }


// void Init(std::vector<Thread<ringqueue_t>>& threads, int num, ringqueue_t& rq, const std::string& nameprefix, func_t<ringqueue_t> func)
// {
//     for (int i = 0; i < num; i++)
//     {
//         std::string name = nameprefix + std::to_string(i + 1);
//         threads.emplace_back(func, rq, name);
//     }
// }

// void InitMaster(std::vector<Thread<ringqueue_t>>& threads, int num, ringqueue_t& rq)
// {
//     Init(threads, num, rq, "master", MasterCore);
// }

// void InitSlaver(std::vector<Thread<ringqueue_t>>& threads, int num, ringqueue_t& rq)
// {
//     Init(threads, num, rq, "slaver", SlaverCore);
// }

// void StartAll(std::vector<Thread<ringqueue_t>>& threads)
// {
//     for (auto& thread : threads)
//         thread.Start();
// }

// void WaitAll(std::vector<Thread<ringqueue_t>>& threads)
// {
//     for (auto& thread : threads)
//         thread.Join();
// }

// int main()
// {
//     srand(time(nullptr));
//     ringqueue_t* rq = new ringqueue_t();
//     std::vector<Thread<ringqueue_t>> threads;
//     InitMaster(threads, 1, *rq);
//     InitSlaver(threads, 2, *rq);
//     StartAll(threads);
//     WaitAll(threads);
//     return 0;
// }